package com.example.dw.admin.service.impl;

import com.example.dw.admin.service.AdminHomeService;
import com.example.dw.mapper.*;
import com.example.dw.entity.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 管理端首页服务实现类
 * @author system
 * @since 2024-01-01
 */
@Slf4j
@Service
public class AdminHomeServiceImpl implements AdminHomeService {

    @Autowired
    private OrderMapper orderMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private CourseMapper courseMapper;
    
    @Autowired
    private QuestionBankMapper questionBankMapper;
    
    @Autowired
    private PackMapper packMapper;
    
    @Autowired
    private AboutMeMapper aboutMeMapper;

    @Override
    public Map<String, Object> getOrderByDay() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 获取今日日期
            String today = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            
            // 查询今日订单数量
            QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
            queryWrapper.like("createdAt", today);
            int todayOrderCount = Math.toIntExact(orderMapper.selectCount(queryWrapper));
            
            // 查询今日订单总金额
            List<Order> todayOrders = orderMapper.selectList(queryWrapper);
            double todayOrderAmount = todayOrders.stream()
                    .mapToDouble(order -> order.getTrxamt() != null ? order.getTrxamt().doubleValue() : 0.0)
                    .sum();
            
            result.put("count", todayOrderCount);
            result.put("amount", todayOrderAmount);
            result.put("date", today);
            
        } catch (Exception e) {
            log.error("获取今日订单统计失败: {}", e.getMessage());
            result.put("count", 0);
            result.put("amount", 0.0);
            result.put("date", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getOrderBySome(Integer limit) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
            queryWrapper.orderByDesc("orderTime").last("LIMIT " + limit);
            List<Order> orders = orderMapper.selectList(queryWrapper);
            
            result.put("orders", orders);
            result.put("count", orders.size());
            
        } catch (Exception e) {
            log.error("获取最新订单列表失败: {}", e.getMessage());
            result.put("orders", new ArrayList<>());
            result.put("count", 0);
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getOrderByAll() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 总订单数
            int totalCount = Math.toIntExact(orderMapper.selectCount(null));
            
            // 总订单金额
            List<Order> allOrders = orderMapper.selectList(null);
            double totalAmount = allOrders.stream()
                    .mapToDouble(order -> order.getTrxamt() != null ? order.getTrxamt().doubleValue() : 0.0)
                    .sum();
            
            // 按状态统计
            QueryWrapper<Order> paidWrapper = new QueryWrapper<>();
            paidWrapper.eq("trxstatus", 1); // 1是已支付状态
            int paidCount = Math.toIntExact(orderMapper.selectCount(paidWrapper));
            
            QueryWrapper<Order> unpaidWrapper = new QueryWrapper<>();
            unpaidWrapper.eq("trxstatus", 0); // 0是未支付状态
            int unpaidCount = Math.toIntExact(orderMapper.selectCount(unpaidWrapper));
            
            result.put("totalCount", totalCount);
            result.put("totalAmount", totalAmount);
            result.put("paidCount", paidCount);
            result.put("unpaidCount", unpaidCount);
            
        } catch (Exception e) {
            log.error("获取订单总数统计失败: {}", e.getMessage());
            result.put("totalCount", 0);
            result.put("totalAmount", 0.0);
            result.put("paidCount", 0);
            result.put("unpaidCount", 0);
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getUserByDay() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 获取今日日期
            String today = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            
            // 查询今日新增用户数量
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.like("createdAt", today);
            int todayUserCount = Math.toIntExact(userMapper.selectCount(queryWrapper));
            
            // 按角色分类统计今日新增
            QueryWrapper<User> studentWrapper = new QueryWrapper<>();
            studentWrapper.like("createdAt", today).eq("role", 0);
            int todayStudentCount = Math.toIntExact(userMapper.selectCount(studentWrapper));
            
            QueryWrapper<User> teacherWrapper = new QueryWrapper<>();
            teacherWrapper.like("createdAt", today).eq("role", 1);
            int todayTeacherCount = Math.toIntExact(userMapper.selectCount(teacherWrapper));
            
            result.put("totalCount", todayUserCount);
            result.put("studentCount", todayStudentCount);
            result.put("teacherCount", todayTeacherCount);
            result.put("date", today);
            
        } catch (Exception e) {
            log.error("获取今日新增用户统计失败: {}", e.getMessage());
            result.put("totalCount", 0);
            result.put("studentCount", 0);
            result.put("teacherCount", 0);
            result.put("date", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getUserByAll() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 总用户数
            int totalCount = Math.toIntExact(userMapper.selectCount(null));
            
            // 按角色分类统计
            QueryWrapper<User> studentWrapper = new QueryWrapper<>();
            studentWrapper.eq("role", 0);
            int studentCount = Math.toIntExact(userMapper.selectCount(studentWrapper));
            
            QueryWrapper<User> teacherWrapper = new QueryWrapper<>();
            teacherWrapper.eq("role", 1);
            int teacherCount = Math.toIntExact(userMapper.selectCount(teacherWrapper));
            
            // 按状态分类统计
            QueryWrapper<User> activeWrapper = new QueryWrapper<>();
            activeWrapper.eq("status", 0); // 0-正常状态
            int activeCount = Math.toIntExact(userMapper.selectCount(activeWrapper));
            
            QueryWrapper<User> disabledWrapper = new QueryWrapper<>();
            disabledWrapper.eq("status", 1); // 1-禁用状态
            int disabledCount = Math.toIntExact(userMapper.selectCount(disabledWrapper));
            
            result.put("totalCount", totalCount);
            result.put("studentCount", studentCount);
            result.put("teacherCount", teacherCount);
            result.put("activeCount", activeCount);
            result.put("disabledCount", disabledCount);
            
        } catch (Exception e) {
            log.error("获取用户总数统计失败: {}", e.getMessage());
            result.put("totalCount", 0);
            result.put("studentCount", 0);
            result.put("teacherCount", 0);
            result.put("activeCount", 0);
            result.put("disabledCount", 0);
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getCourseByAll() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 总课程数
            int totalCount = Math.toIntExact(courseMapper.selectCount(null));
            
            result.put("totalCount", totalCount);
            
        } catch (Exception e) {
            log.error("获取课程总数统计失败: {}", e.getMessage());
            result.put("totalCount", 0);
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getQuestByAll() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 总题库数
            int totalCount = Math.toIntExact(questionBankMapper.selectCount(null));
            
            result.put("totalCount", totalCount);
            
        } catch (Exception e) {
            log.error("获取题库总数统计失败: {}", e.getMessage());
            result.put("totalCount", 0);
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getOrDerByWOrM(Map<String, Object> params) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String period = (String) params.get("period"); // "week" 或 "month"
            LocalDateTime endDate = LocalDateTime.now();
            LocalDateTime startDate;
            
            if ("week".equals(period)) {
                startDate = endDate.minusDays(7);
            } else {
                startDate = endDate.minusDays(30);
            }
            
            // 查询指定时间段的订单
            QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
            queryWrapper.between("createdAt", 
                    startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                    endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            
            List<Order> orders = orderMapper.selectList(queryWrapper);
            int count = orders.size();
            double totalAmount = orders.stream()
                    .mapToDouble(order -> order.getTrxamt() != null ? order.getTrxamt().doubleValue() : 0.0)
                    .sum();
            
            result.put("period", period);
            result.put("count", count);
            result.put("totalAmount", totalAmount);
            result.put("orders", orders);
            result.put("startDate", startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            result.put("endDate", endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            
        } catch (Exception e) {
            log.error("获取时间段订单统计失败: {}", e.getMessage());
            result.put("count", 0);
            result.put("totalAmount", 0.0);
            result.put("orders", new ArrayList<>());
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getPack() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<Pack> packs = packMapper.selectList(null);
            result.put("packs", packs);
            
        } catch (Exception e) {
            log.error("获取用户协议失败: {}", e.getMessage());
            result.put("packs", new ArrayList<>());
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getAboutMe() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // TODO: AboutMeMapper被临时禁用，暂时返回空数据
            // List<AboutMe> aboutMes = aboutMeMapper.selectList(null);
            result.put("aboutMes", new ArrayList<>());
            result.put("message", "About me功能暂时不可用");
            
        } catch (Exception e) {
            log.error("获取关于我们失败: {}", e.getMessage());
            result.put("aboutMes", new ArrayList<>());
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getServer() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // JVM 信息
            Runtime runtime = Runtime.getRuntime();
            RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
            
            // 内存信息
            long totalMemory = runtime.totalMemory();
            long freeMemory = runtime.freeMemory();
            long usedMemory = totalMemory - freeMemory;
            long maxMemory = runtime.maxMemory();
            
            // 运行时间
            long uptime = runtimeMXBean.getUptime();
            long uptimeSeconds = uptime / 1000;
            long uptimeMinutes = uptimeSeconds / 60;
            long uptimeHours = uptimeMinutes / 60;
            long uptimeDays = uptimeHours / 24;
            
            // 系统信息
            Properties props = System.getProperties();
            
            result.put("jvm", Map.of(
                    "version", props.getProperty("java.version"),
                    "vendor", props.getProperty("java.vendor"),
                    "name", runtimeMXBean.getVmName(),
                    "version", runtimeMXBean.getVmVersion()
            ));
            
            result.put("memory", Map.of(
                    "total", formatBytes(totalMemory),
                    "used", formatBytes(usedMemory),
                    "free", formatBytes(freeMemory),
                    "max", formatBytes(maxMemory),
                    "usagePercent", Math.round((double) usedMemory / totalMemory * 100)
            ));
            
            result.put("system", Map.of(
                    "os", props.getProperty("os.name"),
                    "arch", props.getProperty("os.arch"),
                    "version", props.getProperty("os.version"),
                    "processors", runtime.availableProcessors()
            ));
            
            result.put("uptime", Map.of(
                    "days", uptimeDays,
                    "hours", uptimeHours % 24,
                    "minutes", uptimeMinutes % 60,
                    "seconds", uptimeSeconds % 60,
                    "totalMillis", uptime
            ));
            
            result.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            
        } catch (Exception e) {
            log.error("获取服务器状态失败: {}", e.getMessage());
            result.put("error", "获取服务器信息失败");
        }
        
        return result;
    }
    
    /**
     * 格式化字节数
     */
    private String formatBytes(long bytes) {
        if (bytes < 1024) {
            return bytes + " B";
        } else if (bytes < 1024 * 1024) {
            return String.format("%.2f KB", bytes / 1024.0);
        } else if (bytes < 1024 * 1024 * 1024) {
            return String.format("%.2f MB", bytes / (1024.0 * 1024));
        } else {
            return String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024));
        }
    }
} 